From 7166248ac4d31b4c40d63be4f952d35ea678a5ab Mon Sep 17 00:00:00 2001 From: "mjw@wray-m-3.hpl.hp.com" Date: Wed, 18 Aug 2004 09:17:07 +0000 Subject: [PATCH] bitkeeper revision 1.1159.38.1 (41231e93omwWBjFZGIgG3ek6UMbDYA) Refactor device setup code so that the devices do more of the messaging. --- tools/python/xen/lowlevel/xu/xu.c | 6 + tools/python/xen/xend/XendDomainInfo.py | 8 +- tools/python/xen/xend/server/SrvDomain.py | 30 +- tools/python/xen/xend/server/blkif.py | 390 ++++++++------------- tools/python/xen/xend/server/channel.py | 6 +- tools/python/xen/xend/server/controller.py | 4 +- tools/python/xen/xend/server/messages.py | 7 +- tools/python/xen/xend/server/netif.py | 180 ++++------ 8 files changed, 266 insertions(+), 365 deletions(-) diff --git a/tools/python/xen/lowlevel/xu/xu.c b/tools/python/xen/lowlevel/xu/xu.c index d403099cec..3b078e7d33 100644 --- a/tools/python/xen/lowlevel/xu/xu.c +++ b/tools/python/xen/lowlevel/xu/xu.c @@ -426,6 +426,12 @@ static PyObject *xu_message_get_payload(PyObject *self, PyObject *args) C2P(netif_fe_interface_status_changed_t, handle, Int, Long); C2P(netif_fe_interface_status_changed_t, status, Int, Long); C2P(netif_fe_interface_status_changed_t, evtchn, Int, Long); + C2P(netif_fe_interface_status_changed_t, mac[0], Int, Long); + C2P(netif_fe_interface_status_changed_t, mac[1], Int, Long); + C2P(netif_fe_interface_status_changed_t, mac[2], Int, Long); + C2P(netif_fe_interface_status_changed_t, mac[3], Int, Long); + C2P(netif_fe_interface_status_changed_t, mac[4], Int, Long); + C2P(netif_fe_interface_status_changed_t, mac[5], Int, Long); return dict; case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED): C2P(netif_fe_driver_status_changed_t, status, Int, Long); diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 602575d0ba..d2bff39b04 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -1074,8 +1074,8 @@ def vm_dev_vif(vm, val, index): @param index: vif index @return: deferred """ - if vm.netif_backend: - raise VmError('vif: vif in netif backend domain') + #if vm.netif_backend: + # raise VmError('vif: vif in netif backend domain') vif = vm.next_device_index('vif') vmac = sxp.child_value(val, "mac") backend = vm.get_device_backend('vif') @@ -1098,8 +1098,8 @@ def vm_dev_vbd(vm, val, index): @param index: vbd index @return: deferred """ - if vm.blkif_backend: - raise VmError('vbd: vbd in blkif backend domain') + #if vm.blkif_backend: + # raise VmError('vbd: vbd in blkif backend domain') uname = sxp.child_value(val, 'uname') if not uname: raise VmError('vbd: Missing uname') diff --git a/tools/python/xen/xend/server/SrvDomain.py b/tools/python/xen/xend/server/SrvDomain.py index aed8fd7e57..50aa355e62 100644 --- a/tools/python/xen/xend/server/SrvDomain.py +++ b/tools/python/xen/xend/server/SrvDomain.py @@ -48,7 +48,7 @@ class SrvDomain(SrvDir): fn = FormFn(self.xd.domain_shutdown, [['dom', 'str'], ['reason', 'str']]) - val = fn(req.args, {'dom': self.dom.name}) + val = fn(req.args, {'dom': self.dom.id}) req.setResponseCode(http.ACCEPTED) req.setHeader("Location", "%s/.." % req.prePathURL()) return val @@ -57,7 +57,7 @@ class SrvDomain(SrvDir): fn = FormFn(self.xd.domain_destroy, [['dom', 'str'], ['reason', 'str']]) - val = fn(req.args, {'dom': self.dom.name}) + val = fn(req.args, {'dom': self.dom.id}) req.setHeader("Location", "%s/.." % req.prePathURL()) return val @@ -65,7 +65,7 @@ class SrvDomain(SrvDir): fn = FormFn(self.xd.domain_save, [['dom', 'str'], ['file', 'str']]) - deferred = fn(req.args, {'dom': self.dom.name}) + deferred = fn(req.args, {'dom': self.dom.id}) deferred.addCallback(self._op_save_cb, req) deferred.addErrback(self._op_save_err, req) return deferred @@ -81,7 +81,7 @@ class SrvDomain(SrvDir): fn = FormFn(self.xd.domain_migrate, [['dom', 'str'], ['destination', 'str']]) - deferred = fn(req.args, {'dom': self.dom.name}) + deferred = fn(req.args, {'dom': self.dom.id}) print 'op_migrate>', deferred deferred.addCallback(self._op_migrate_cb, req) deferred.addErrback(self._op_migrate_err, req) @@ -107,7 +107,7 @@ class SrvDomain(SrvDir): fn = FormFn(self.xd.domain_pincpu, [['dom', 'str'], ['cpu', 'int']]) - val = fn(req.args, {'dom': self.dom.name}) + val = fn(req.args, {'dom': self.dom.id}) return val def op_cpu_bvt_set(self, op, req): @@ -118,7 +118,7 @@ class SrvDomain(SrvDir): ['warpvalue', 'int'], ['warpl', 'long'], ['warpu', 'long']]) - val = fn(req.args, {'dom': self.dom.name}) + val = fn(req.args, {'dom': self.dom.id}) return val def op_cpu_fbvt_set(self, op, req): @@ -128,7 +128,7 @@ class SrvDomain(SrvDir): ['warp', 'int'], ['warpl', 'int'], ['warpu', 'int']]) - val = fn(req.args, {'dom': self.dom.name}) + val = fn(req.args, {'dom': self.dom.id}) return val def op_cpu_atropos_set(self, op, req): @@ -138,21 +138,21 @@ class SrvDomain(SrvDir): ['slice', 'int'], ['latency', 'int'], ['xtratime', 'int']]) - val = fn(req.args, {'dom': self.dom.name}) + val = fn(req.args, {'dom': self.dom.id}) return val def op_maxmem_set(self, op, req): fn = FormFn(self.xd.domain_maxmem_set, [['dom', 'str'], ['memory', 'int']]) - val = fn(req.args, {'dom': self.dom.name}) + val = fn(req.args, {'dom': self.dom.id}) return val def op_device_create(self, op, req): fn = FormFn(self.xd.domain_device_create, [['dom', 'str'], ['config', 'sxpr']]) - d = fn(req.args, {'dom': self.dom.name}) + d = fn(req.args, {'dom': self.dom.id}) return d def op_device_destroy(self, op, req): @@ -160,29 +160,29 @@ class SrvDomain(SrvDir): [['dom', 'str'], ['type', 'str'], ['idx', 'str']]) - val = fn(req.args, {'dom': self.dom.name}) + val = fn(req.args, {'dom': self.dom.id}) return val def op_vifs(self, op, req): - devs = self.xd.domain_vif_ls(self.dom.name) + devs = self.xd.domain_vif_ls(self.dom.id) return [ dev.sxpr() for dev in devs ] def op_vif(self, op, req): fn = FormFn(self.xd.domain_vif_get, [['dom', 'str'], ['vif', 'str']]) - val = fn(req.args, {'dom': self.dom.name}) + val = fn(req.args, {'dom': self.dom.id}) return val def op_vbds(self, op, req): - devs = self.xd.domain_vbd_ls(self.dom.name) + devs = self.xd.domain_vbd_ls(self.dom.id) return [ dev.sxpr() for dev in devs ] def op_vbd(self, op, req): fn = FormFn(self.xd.domain_vbd_get, [['dom', 'str'], ['vbd', 'str']]) - val = fn(req.args, {'dom': self.dom.name}) + val = fn(req.args, {'dom': self.dom.id}) return val def render_POST(self, req): diff --git a/tools/python/xen/xend/server/blkif.py b/tools/python/xen/xend/server/blkif.py index bea848bfcf..c142e59da8 100755 --- a/tools/python/xen/xend/server/blkif.py +++ b/tools/python/xen/xend/server/blkif.py @@ -22,74 +22,7 @@ class BlkifBackendController(controller.BackendController): self.addMethod(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED, self.recv_be_driver_status_changed) - self.attached = 1 self.registerChannel() - - def respond_be_create(self, msg, d): - """Response handler for a be_create message. - Calls I{d} with the block interface created. - - @param msg: message - @type msg: xu message - @param d: deferred to call - @type d: Deferred - """ - val = unpackMsg('blkif_be_create_t', msg) - blkif = self.factory.getInstanceByDom(val['domid']) - d.callback(blkif) - - def respond_be_connect(self, msg): - """Response handler for a be_connect message. - - @param msg: message - @type msg: xu message - """ - val = unpackMsg('blkif_be_connect_t', msg) - blkif = self.factory.getInstanceByDom(val['domid']) - if blkif: - blkif.send_fe_interface_status_changed() - else: - pass - - def respond_be_vbd_create(self, msg, dev, d): - """Response handler for a be_vbd_create message. - Tries to grow the vbd, and passes the deferred I{d} on for - the grow to call. - - @param msg: message - @type msg: xu message - @param dev: device - @type dev: BlkDev - @param d: deferred to call - @type d: Deferred - """ - val = unpackMsg('blkif_be_vbd_create_t', msg) - blkif = self.factory.getInstanceByDom(val['domid']) - if blkif: - d1 = defer.Deferred() - d1.addCallback(self.respond_be_vbd_grow, dev, d) - if d: d1.addErrback(d.errback) - blkif.send_be_vbd_grow(val['vdevice'], response=d1) - else: - pass - - def respond_be_vbd_grow(self, msg, dev, d): - """Response handler for a be_vbd_grow message. - - @param msg: message - @type msg: xu message - @param dev: device - @type dev: BlkDev - @param d: deferred to call - @type d: Deferred or None - """ - val = unpackMsg('blkif_be_vbd_grow_t', msg) - status = val['status'] - if status != BLKIF_BE_STATUS_OKAY: - raise XendError("Adding extent to vbd failed: device %x, error %d" - % (val['extent.device'], status)) - if d: - d.callback(dev) def recv_be_driver_status_changed(self, msg, req): """Request handler for be_driver_status_changed messages. @@ -101,11 +34,6 @@ class BlkifBackendController(controller.BackendController): """ val = unpackMsg('blkif_be_driver_status_changed_t', msg) status = val['status'] - if status == BLKIF_DRIVER_STATUS_UP and not self.attached: - for blkif in self.factory.getInstances(): - if blkif.backendController == self: - blkif.detach() - class BlkifControllerFactory(controller.SplitControllerFactory): """Factory for creating block device interface controllers. @@ -113,7 +41,6 @@ class BlkifControllerFactory(controller.SplitControllerFactory): def __init__(self): controller.SplitControllerFactory.__init__(self) - self.attached = 1 def createInstance(self, dom, recreate=0, backend=0): """Create a block device controller for a domain. @@ -125,20 +52,14 @@ class BlkifControllerFactory(controller.SplitControllerFactory): @return: deferred @rtype: twisted.internet.defer.Deferred """ - d = defer.Deferred() blkif = self.getInstanceByDom(dom) if blkif: + d = defer.Deferred() d.callback(blkif) else: blkif = BlkifController(self, dom, backend) self.addInstance(blkif) - if recreate: - d.callback(blkif) - else: - d1 = defer.Deferred() - d1.addCallback(blkif.backendController.respond_be_create, d) - d1.addErrback(d.errback) - blkif.send_be_create(response=d1) + d = blkif.connect(recreate=recreate) return d def getDomainDevices(self, dom): @@ -158,7 +79,7 @@ class BlkifControllerFactory(controller.SplitControllerFactory): @param dom: domain @type dom: int @param vdev: device index - @type vedv: int + @type vdev: int @return: device @rtype: device """ @@ -168,66 +89,6 @@ class BlkifControllerFactory(controller.SplitControllerFactory): def createBackendController(self, dom): return BlkifBackendController(self, dom) - def setControlDomain(self, dom, recreate=0): - """Set the back-end block device controller domain. - - @param dom: domain - @type dom: int - @param recreate: if true it's a recreate (after xend restart) - @type recreate: int - """ - if self.dom == dom: return - self.deregisterChannel() - if not recreate: - self.attached = 0 - self.dom = dom - self.registerChannel() - - def getControlDomain(self): - """Get the back-end block device controller domain. - - @return: domain - @rtype: int - """ - return self.dom - - def reattachDevice(self, dom, vdev): - """Reattach a device (on changing control domain). - - @param dom: domain - @type dom: int - @param vdev: device index - @type vdev: int - """ - blkif = self.getInstanceByDom(dom) - if blkif: - blkif.reattachDevice(vdev) - self.attached = self.devicesAttached() - if self.attached: - self.reattached() - - def devicesAttached(self): - """Check if all devices are attached. - - @return: true if all devices attached - @rtype: bool - """ - attached = 1 - for blkif in self.getInstances(): - if not blkif.attached: - attached = 0 - break - return attached - - def reattached(self): - """Notify all block interfaces we have been reattached - (after changing control domain). - """ - for blkif in self.getInstances(): - blkif.reattached() - - - class BlkDev(controller.Dev): """Info record for a block device. """ @@ -241,7 +102,9 @@ class BlkDev(controller.Dev): self.device = segment['device'] self.start_sector = segment['start_sector'] self.nr_sectors = segment['nr_sectors'] - self.attached = 1 + + def getBackendController(self): + return self.controller.backendController def readonly(self): return 'w' not in self.mode @@ -260,7 +123,80 @@ class BlkDev(controller.Dev): def destroy(self): log.debug("Destroying vbd domain=%d vdev=%d", self.controller.dom, self.vdev) - self.controller.send_be_vbd_destroy(self.vdev) + self.send_be_vbd_destroy() + + def attach(self, d): + """Attach the device to its controller. + + @param d: deferred to call with the device on success + """ + d1 = defer.Deferred() + d1.addCallback(self.respond_be_vbd_create, d) + d1.addErrback(d.errback) + self.send_be_vbd_create(response=d1) + + def send_be_vbd_create(self, response=None): + msg = packMsg('blkif_be_vbd_create_t', + { 'domid' : self.controller.dom, + 'blkif_handle' : self.controller.handle, + 'vdevice' : self.vdev, + 'readonly' : self.readonly() }) + self.getBackendController().writeRequest(msg, response=response) + + def respond_be_vbd_create(self, msg, d): + """Response handler for a be_vbd_create message. + Tries to grow the vbd. + + @param msg: message + @type msg: xu message + @param d: deferred to call + @type d: Deferred + """ + val = unpackMsg('blkif_be_vbd_create_t', msg) + d1 = defer.Deferred() + d1.addCallback(self.respond_be_vbd_grow, d) + if d: d1.addErrback(d.errback) + self.send_be_vbd_grow(response=d1) + + def send_be_vbd_grow(self, response=None): + msg = packMsg('blkif_be_vbd_grow_t', + { 'domid' : self.controller.dom, + 'blkif_handle' : self.controller.handle, + 'vdevice' : self.vdev, + 'extent.device' : self.device, + 'extent.sector_start' : self.start_sector, + 'extent.sector_length' : self.nr_sectors }) + self.getBackendController().writeRequest(msg, response=response) + + def respond_be_vbd_grow(self, msg, d): + """Response handler for a be_vbd_grow message. + + @param msg: message + @type msg: xu message + @param d: deferred to call + @type d: Deferred or None + """ + val = unpackMsg('blkif_be_vbd_grow_t', msg) + status = val['status'] + if status != BLKIF_BE_STATUS_OKAY: + err = XendError("Adding extent to vbd failed: device %d, error %d" + % (self.vdev, status)) + #if(d): + # d.errback(err) + raise err + if d: + d.callback(self) + + def send_be_vbd_destroy(self, response=None): + log.debug('>BlkDev>send_be_vbd_destroy> dom=%d vdev=%d', + self.controller.dom, self.vdev) + msg = packMsg('blkif_be_vbd_destroy_t', + { 'domid' : self.controller.dom, + 'blkif_handle' : self.controller.handle, + 'vdevice' : self.vdev }) + self.controller.delDevice(self.vdev) + self.getBackendController().writeRequest(msg, response=response) + class BlkifController(controller.SplitController): """Block device interface controller. Handles all block devices @@ -268,6 +204,10 @@ class BlkifController(controller.SplitController): """ def __init__(self, factory, dom, backend): + """Create a block device controller. + The controller must be connected using connect() before it can be used. + Do not call directly - use createInstance() on the factory instead. + """ controller.SplitController.__init__(self, factory, dom, backend) self.devices = {} self.addMethod(CMSG_BLKIF_FE, @@ -276,7 +216,7 @@ class BlkifController(controller.SplitController): self.addMethod(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_CONNECT, self.recv_fe_interface_connect) - self.attached = 1 + self.handle = 0 self.evtchn = None self.registerChannel() @@ -311,6 +251,10 @@ class BlkifController(controller.SplitController): self.devices[vdev] = dev return dev + def delDevice(self, vdev): + if vdev in self.devices: + del self.devices[vdev] + def attachDevice(self, vdev, mode, segment, recreate=0): """Attach a device to the specified interface. On success the returned deferred will be called with the device. @@ -332,63 +276,75 @@ class BlkifController(controller.SplitController): if recreate: d.callback(dev) else: - d1 = defer.Deferred() - d1.addCallback(self.backendController.respond_be_vbd_create, dev, d) - d1.addErrback(d.errback) - self.send_be_vbd_create(vdev, response=d1) + dev.attach(d) return d def destroy(self): - def cb_destroy(val): - self.send_be_destroy() + """Destroy the controller and all devices. + """ log.debug("Destroying blkif domain=%d", self.dom) - d = defer.Deferred() - d.addCallback(cb_destroy) - self.send_be_disconnect(response=d) + self.destroyDevices() + self.disconnect() def destroyDevices(self): + """Destroy all devices. + """ for dev in self.getDevices(): dev.destroy() - def detach(self): - """Detach all devices, when the back-end control domain has changed. - """ - self.attached = 0 - for dev in self.devices.values(): - dev.attached = 0 - d1 = defer.Deferred() - d1.addCallback(self.backendController.respond_be_vbd_create, None, None) - self.send_be_vbd_create(vdev, response=d1) - - def reattachDevice(self, vdev): - """Reattach a device, when the back-end control domain has changed. + def connect(self, recreate=0): + """Connect the controller to the blkif control interface. + + @param recreate: true if after xend restart + @return: deferred """ - dev = self.devices[vdev] - dev.attached = 1 - attached = 1 - for dev in self.devices.values(): - if not dev.attached: - attached = 0 - break - self.attached = attached - return self.attached - - def reattached(self): - """All devices have been reattached after the back-end control - domain has changed. + log.debug("Connecting blkif domain=%d", self.dom) + d = defer.Deferred() + if recreate: + d.callback(self) + else: + def cbresp(msg): + return self + d.addCallback(cbresp) + self.send_be_create(response=d) + return d + + def send_be_create(self, response=None): + msg = packMsg('blkif_be_create_t', + { 'domid' : self.dom, + 'blkif_handle' : self.handle }) + self.backendController.writeRequest(msg, response=response) + + def disconnect(self): + """Disconnect from the blkif control interface and destroy it. """ - msg = packMsg('blkif_fe_interface_status_changed_t', - { 'handle' : 0, - 'status' : BLKIF_INTERFACE_STATUS_DISCONNECTED}) - self.writeRequest(msg) + def cb_destroy(val): + self.send_be_destroy() + d = defer.Deferred() + d.addCallback(cb_destroy) + self.send_be_disconnect(response=d) + + def send_be_disconnect(self, response=None): + log.debug('>BlkifController>send_be_disconnect> dom=%d', self.dom) + msg = packMsg('blkif_be_disconnect_t', + { 'domid' : self.dom, + 'blkif_handle' : self.handle }) + self.backendController.writeRequest(msg, response=response) + def send_be_destroy(self, response=None): + log.debug('>BlkifController>send_be_destroy> dom=%d', self.dom) + msg = packMsg('blkif_be_destroy_t', + { 'domid' : self.dom, + 'blkif_handle' : self.handle }) + self.backendController.writeRequest(msg, response=response) + def recv_fe_driver_status_changed(self, msg, req): msg = packMsg('blkif_fe_interface_status_changed_t', - { 'handle' : 0, + { 'handle' : self.handle, 'status' : BLKIF_INTERFACE_STATUS_DISCONNECTED, 'evtchn' : 0 }) self.writeRequest(msg) - + def recv_fe_interface_connect(self, msg, req): val = unpackMsg('blkif_fe_interface_connect_t', msg) self.evtchn = channel.eventChannel(0, self.dom) @@ -400,63 +356,23 @@ class BlkifController(controller.SplitController): 'evtchn' : self.evtchn['port1'], 'shmem_frame' : val['shmem_frame'] }) d = defer.Deferred() - d.addCallback(self.backendController.respond_be_connect) + d.addCallback(self.respond_be_connect) self.backendController.writeRequest(msg, response=d) + def respond_be_connect(self, msg): + """Response handler for a be_connect message. + + @param msg: message + @type msg: xu message + """ + val = unpackMsg('blkif_be_connect_t', msg) + self.send_fe_interface_status_changed() + def send_fe_interface_status_changed(self, response=None): msg = packMsg('blkif_fe_interface_status_changed_t', - { 'handle' : 0, + { 'handle' : self.handle, 'status' : BLKIF_INTERFACE_STATUS_CONNECTED, 'evtchn' : self.evtchn['port2'] }) self.writeRequest(msg, response=response) - - def send_be_create(self, response=None): - msg = packMsg('blkif_be_create_t', - { 'domid' : self.dom, - 'blkif_handle' : 0 }) - self.backendController.writeRequest(msg, response=response) - - def send_be_disconnect(self, response=None): - log.debug('>BlkifController>send_be_disconnect> dom=%d', self.dom) - msg = packMsg('blkif_be_disconnect_t', - { 'domid' : self.dom, - 'blkif_handle' : 0 }) - self.backendController.writeRequest(msg, response=response) - - def send_be_destroy(self, response=None): - log.debug('>BlkifController>send_be_destroy> dom=%d', self.dom) - msg = packMsg('blkif_be_destroy_t', - { 'domid' : self.dom, - 'blkif_handle' : 0 }) - self.backendController.writeRequest(msg, response=response) - - def send_be_vbd_create(self, vdev, response=None): - dev = self.devices[vdev] - msg = packMsg('blkif_be_vbd_create_t', - { 'domid' : self.dom, - 'blkif_handle' : 0, - 'vdevice' : dev.vdev, - 'readonly' : dev.readonly() }) - self.backendController.writeRequest(msg, response=response) - - def send_be_vbd_grow(self, vdev, response=None): - dev = self.devices[vdev] - msg = packMsg('blkif_be_vbd_grow_t', - { 'domid' : self.dom, - 'blkif_handle' : 0, - 'vdevice' : dev.vdev, - 'extent.device' : dev.device, - 'extent.sector_start' : dev.start_sector, - 'extent.sector_length' : dev.nr_sectors }) - self.backendController.writeRequest(msg, response=response) - - def send_be_vbd_destroy(self, vdev, response=None): - log.debug('>BlkifController>send_be_vbd_destroy> dom=%d vdev=%d', self.dom, vdev) - dev = self.devices[vdev] - msg = packMsg('blkif_be_vbd_destroy_t', - { 'domid' : self.dom, - 'blkif_handle' : 0, - 'vdevice' : dev.vdev }) - del self.devices[vdev] - self.backendController.writeRequest(msg, response=response) + diff --git a/tools/python/xen/xend/server/channel.py b/tools/python/xen/xend/server/channel.py index d78ba252cb..4c6dbadd17 100755 --- a/tools/python/xen/xend/server/channel.py +++ b/tools/python/xen/xend/server/channel.py @@ -333,13 +333,15 @@ class Channel(BaseChannel): (ty, subty) = self.getMessageType(msg) #todo: Must respond before writing any more messages. #todo: Should automate this (respond on write) - self.port.write_response(msg) + responded = 0 dev = self.getDevice(ty) if dev: - dev.requestReceived(msg, ty, subty) + responded = dev.requestReceived(msg, ty, subty) else: print ("requestReceived> No device: Message type %s %d:%d" % (msgTypeName(ty, subty), ty, subty)), self + if not responded: + self.port.write_response(msg) def handleResponses(self): work = 0 diff --git a/tools/python/xen/xend/server/controller.py b/tools/python/xen/xend/server/controller.py index cea9c38dfb..28662207bb 100755 --- a/tools/python/xen/xend/server/controller.py +++ b/tools/python/xen/xend/server/controller.py @@ -125,12 +125,14 @@ class CtrlMsgRcvr: if DEBUG: print 'requestReceived>', printMsg(msg, all=1) + responded = 0 method = self.getMethod(type, subtype) if method: - method(msg, 1) + responded = method(msg, 1) elif DEBUG: print ('requestReceived> No handler: Message type %s %d:%d' % (msgTypeName(type, subtype), type, subtype)), self + return responded def responseReceived(self, msg, type, subtype): """Dispatch a response to handlers. diff --git a/tools/python/xen/xend/server/messages.py b/tools/python/xen/xend/server/messages.py index e966ec9003..8d68d95887 100644 --- a/tools/python/xen/xend/server/messages.py +++ b/tools/python/xen/xend/server/messages.py @@ -215,7 +215,7 @@ def packMsg(ty, params): else: args[k] = v msg = xu.message(major, minor, msgid, args) - if DEBUG: print 'unpackMsg', args if isinstance(args, types.StringType): - args = { 'value': args } + args = {'value': args} else: mac = [0, 0, 0, 0, 0, 0] macs = [] @@ -284,5 +285,5 @@ def printMsg(msg, out=sys.stdout, all=0): ty = msgTypeName(major, minor) print >>out, 'message:', 'type=', ty, '%d:%d' % (major, minor), 'id=%d' % msgid if all: - print >>out, 'payload=', unpackMsg(ty, msg) + print >>out, 'payload=', msg.get_payload() diff --git a/tools/python/xen/xend/server/netif.py b/tools/python/xen/xend/server/netif.py index f4247c670f..a5add8e7fb 100755 --- a/tools/python/xen/xend/server/netif.py +++ b/tools/python/xen/xend/server/netif.py @@ -27,30 +27,11 @@ class NetifBackendController(controller.BackendController): self.addMethod(CMSG_NETIF_BE, CMSG_NETIF_BE_DRIVER_STATUS_CHANGED, self.recv_be_driver_status_changed) - self.attached = 1 self.registerChannel() - def respond_be_connect(self, msg): - val = unpackMsg('netif_be_connect_t', msg) - dom = val['domid'] - vif = val['netif_handle'] - netif = self.factory.getInstanceByDom(dom) - if netif: - netif.send_interface_connected(vif) - else: - log.warning("respond_be_connect> unknown vif dom=%d vif=%d", dom, vif) - pass - def recv_be_driver_status_changed(self, msg, req): val = unpackMsg('netif_be_driver_status_changed_t', msg) status = val['status'] - if status == NETIF_DRIVER_STATUS_UP and not self.attached: - # If we are not attached the driver domain was changed, and - # this signals the new driver domain is ready. - for netif in self.factory.getInstances(): - if netif.backendController == self: - netif.reattach_devices() - self.attached = 1 class NetifControllerFactory(controller.SplitControllerFactory): """Factory for creating network interface controllers. @@ -58,7 +39,6 @@ class NetifControllerFactory(controller.SplitControllerFactory): def __init__(self): controller.ControllerFactory.__init__(self) - self.attached = 1 def createInstance(self, dom, recreate=0, backend=0): """Create or find the network interface controller for a domain. @@ -95,26 +75,6 @@ class NetifControllerFactory(controller.SplitControllerFactory): def createBackendController(self, dom): return NetifBackendController(self, dom) - def setControlDomain(self, dom, recreate=0): - """Set the 'back-end' device driver domain. - - @param dom: domain - @param recreate: if true this is a recreate (xend restarted) - """ - if self.dom == dom: return - self.deregisterChannel() - if not recreate: - self.attached = 0 - self.dom = dom - self.registerChannel() - - def getControlDomain(self): - """Get the domain id of the back-end control domain. - - @return domain id - """ - return self.dom - class NetDev(controller.Dev): """Info record for a network device. """ @@ -125,6 +85,9 @@ class NetDev(controller.Dev): self.evtchn = None self.configure(config) + def getBackendController(self): + return self.controller.backendController + def configure(self, config): self.config = config self.mac = None @@ -205,19 +168,76 @@ class NetDev(controller.Dev): if vnet: vnet.vifctl(op, self.get_vifname(), self.get_mac()) + def attach(self, d): + print 'attach>', d + self.send_be_create(response=d) + + def send_be_create(self, response=None): + msg = packMsg('netif_be_create_t', + { 'domid' : self.controller.dom, + 'netif_handle' : self.vif, + 'mac' : self.mac }) + self.getBackendController().writeRequest(msg, response=response) + def destroy(self): """Destroy the device's resources and disconnect from the back-end device controller. """ def cb_destroy(val): - self.controller.send_be_destroy(self.vif) + self.send_be_destroy() log.debug("Destroying vif domain=%d vif=%d", self.controller.dom, self.vif) self.vifctl('down') d = defer.Deferred() d.addCallback(cb_destroy) - self.controller.send_be_disconnect(self.vif, response=d) + self.send_be_disconnect(response=d) + + def send_be_disconnect(self, response=None): + msg = packMsg('netif_be_disconnect_t', + { 'domid' : self.controller.dom, + 'netif_handle' : self.vif }) + self.getBackendController().writeRequest(msg, response=response) + + def send_be_destroy(self, response=None): + msg = packMsg('netif_be_destroy_t', + { 'domid' : self.controller.dom, + 'netif_handle' : self.vif }) + self.controller.delDevice(self.vif) + self.getBackendController().writeRequest(msg, response=response) + + def recv_fe_interface_connect(self, val, req): + if not req: return + self.evtchn = channel.eventChannel(0, self.controller.dom) + msg = packMsg('netif_be_connect_t', + { 'domid' : self.controller.dom, + 'netif_handle' : self.vif, + 'evtchn' : self.evtchn['port1'], + 'tx_shmem_frame' : val['tx_shmem_frame'], + 'rx_shmem_frame' : val['rx_shmem_frame'] }) + d = defer.Deferred() + d.addCallback(self.respond_be_connect) + self.getBackendController().writeRequest(msg, response=d) + def respond_be_connect(self, msg): + val = unpackMsg('netif_be_connect_t', msg) + dom = val['domid'] + vif = val['netif_handle'] + print 'respond_be_connect>', ' dom=', dom, ' vif=', vif + print 'respond_be_connect>', 'self.dom=', self.controller.dom, 'self.vif=', self.vif + msg = packMsg('netif_fe_interface_status_changed_t', + { 'handle' : self.vif, + 'status' : NETIF_INTERFACE_STATUS_CONNECTED, + 'evtchn' : self.evtchn['port2'], + 'mac' : self.mac }) + self.controller.writeRequest(msg) + def attach_fe_device(self): + msg = packMsg('netif_fe_interface_status_changed_t', + { 'handle' : self.vif, + 'status' : NETIF_INTERFACE_STATUS_DISCONNECTED, + 'evtchn' : 0, + 'mac' : self.mac }) + self.controller.writeRequest(msg) + class NetifController(controller.SplitController): """Network interface controller. Handles all network devices for a domain. """ @@ -266,6 +286,10 @@ class NetifController(controller.SplitController): self.devices[vif] = dev return dev + def delDevice(self, vif): + if vif in self.devices: + del self.devices[vif] + def destroy(self): """Destroy the controller and all devices. """ @@ -285,79 +309,29 @@ class NetifController(controller.SplitController): @param recreate: recreate flag (true after xend restart) @return: deferred """ - self.addDevice(vif, config) + dev = self.addDevice(vif, config) d = defer.Deferred() if recreate: d.callback(self) else: - self.send_be_create(vif, response=d) + dev.attach(d) return d - def reattach_devices(self): - """Reattach all devices when the back-end control domain has changed. - """ - self.send_be_create(vif) - self.attach_fe_devices() - - def attach_fe_devices(self): - for dev in self.devices.values(): - msg = packMsg('netif_fe_interface_status_changed_t', - { 'handle' : dev.vif, - 'status' : NETIF_INTERFACE_STATUS_DISCONNECTED, - 'evtchn' : 0, - 'mac' : dev.mac }) - self.writeRequest(msg) - def recv_fe_driver_status_changed(self, msg, req): if not req: return msg = packMsg('netif_fe_driver_status_changed_t', { 'status' : NETIF_DRIVER_STATUS_UP, 'nr_interfaces' : len(self.devices) }) self.writeRequest(msg) - self.attach_fe_devices() - + for dev in self.devices.values(): + dev.attach_fe_device() + def recv_fe_interface_connect(self, msg, req): val = unpackMsg('netif_fe_interface_connect_t', msg) - dev = self.devices[val['handle']] - dev.evtchn = channel.eventChannel(0, self.dom) - msg = packMsg('netif_be_connect_t', - { 'domid' : self.dom, - 'netif_handle' : dev.vif, - 'evtchn' : dev.evtchn['port1'], - 'tx_shmem_frame' : val['tx_shmem_frame'], - 'rx_shmem_frame' : val['rx_shmem_frame'] }) - d = defer.Deferred() - d.addCallback(self.backendController.respond_be_connect) - self.backendController.writeRequest(msg, response=d) - - def send_interface_connected(self, vif, response=None): - dev = self.devices[vif] - msg = packMsg('netif_fe_interface_status_changed_t', - { 'handle' : dev.vif, - 'status' : NETIF_INTERFACE_STATUS_CONNECTED, - 'evtchn' : dev.evtchn['port2'], - 'mac' : dev.mac }) - self.writeRequest(msg, response=response) - - def send_be_create(self, vif, response=None): - dev = self.devices[vif] - msg = packMsg('netif_be_create_t', - { 'domid' : self.dom, - 'netif_handle' : dev.vif, - 'mac' : dev.mac }) - self.backendController.writeRequest(msg, response=response) - - def send_be_disconnect(self, vif, response=None): - dev = self.devices[vif] - msg = packMsg('netif_be_disconnect_t', - { 'domid' : self.dom, - 'netif_handle' : dev.vif }) - self.backendController.writeRequest(msg, response=response) + vif = val['handle'] + dev = self.devices.get(vif) + if dev: + dev.recv_fe_interface_connect(val, req) + else: + log.error('Received netif_fe_interface_connect for unknown vif: '+vif) - def send_be_destroy(self, vif, response=None): - dev = self.devices[vif] - del self.devices[vif] - msg = packMsg('netif_be_destroy_t', - { 'domid' : self.dom, - 'netif_handle' : vif }) - self.backendController.writeRequest(msg, response=response) -- 2.30.2